import socket
import threading
import time

# Server address and port
SERVER_IP = '10.0.1.2'
SERVER_PORT = 6666

def transmit_data_to_server(client_socket):
    """
    Function to send messages to the server in a separate thread.
    """
    sequence_num = 0
    try:
        while True:
            # Prepare the message to send
            message_to_send = f'seq={sequence_num} This is a unique and detailed message from the client to the server at {SERVER_IP}.'
            # Send the message to the server
            client_socket.send(message_to_send.encode('utf-8'))
            sequence_num += 1
            # Wait for 1 second before sending the next message
            time.sleep(1)
    except Exception as e:
        print(f'An error occurred: {e}')

def receive_data_from_server(client_socket):
    """
    Function to receive messages from the server in a separate thread.
    """
    try:
        while True:
            # Receive data from the server
            incoming_data = client_socket.recv(1024)
            if incoming_data:
                # Get the server address and port
                server_ip, server_port = client_socket.getpeername()
                # Decode the received data from bytes to string
                incoming_message = incoming_data.decode("utf-8")
                # Print the received message
                print(f'Data received from server ({server_ip}:{server_port}): {incoming_message}')
            else:
                print('Server connection closed')
                break
    except Exception as e:
        print(f'An error occurred: {e}')

def initiate_client():
    """
    Function to start the client and connect to the server.
    """
    # Create a TCP/IP socket
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
        print('TCP client is connecting to the server...')
        # Connect to the server
        client_socket.connect((SERVER_IP, SERVER_PORT))

        # Create threads for sending and receiving messages
        transmit_thread = threading.Thread(target=transmit_data_to_server, args=(client_socket,))
        receive_thread = threading.Thread(target=receive_data_from_server, args=(client_socket,))

        # Start the threads
        transmit_thread.start()
        receive_thread.start()

        # Wait for the threads to finish
        transmit_thread.join()
        receive_thread.join()

if __name__ == '__main__':
    initiate_client()
